#include "cpu/exec/template-start.h"

#define instr jmp

static void do_execute() {
	cpu.eip += op_src->val;
	print_asm(str(instr) " %x", cpu.eip + 1 + DATA_BYTE);
}

make_instr_helper(si)
#if DATA_BYTE == 4
make_helper(jmp_rm_l) {
	int len = decode_rm_l(eip + 1);
	cpu.eip = op_src->val - (len + 1);
	print_asm(str(instr) " *%s", op_src->str);
	return len + 1;
}


extern Segment_des *Seg_des;
Segment_des new_Seg_des;

static void load_sreg(uint8_t sreg_no) {
	//get the index of the segment descriptor
    uint16_t index = cpu.reg[sreg_no].selector >> 3;
	//get the segment descriptor
	Seg_des->part1.val1 = lnaddr_read(cpu.gdtr.base + (index << 3), 4);
	Seg_des->part2.val2 = lnaddr_read(cpu.gdtr.base + (index << 3) + 4, 4);
	//get the base and limit of the segment descriptor
	cpu.reg[sreg_no].base = (uint32_t)Seg_des -> part1.base1 
						  + ((uint32_t)Seg_des -> part2.base2 << 16) 
						  + ((uint32_t)Seg_des -> part2.base3 << 24);
	//get the limit of the segment descriptor
	cpu.reg[sreg_no].limit = ((uint32_t)Seg_des->part1.limit1) 
						   + ((uint32_t)Seg_des->part2.limit2 << 16)
						   + (((uint32_t)0xfff) << 24);
	
	if(Seg_des->part2.g == 1) {
		cpu.reg[sreg_no].limit <<= 12;
	}
}

make_helper(ljmp) {
	Seg_des = &new_Seg_des;
    uint32_t op1 = instr_fetch(cpu.eip + 1, 4);
    uint16_t op2 = instr_fetch(cpu.eip + 5, 2);

    cpu.eip = op1;
    cpu.reg[R_CS].selector = op2;
    load_sreg(R_CS);
    print_asm_template2();
    return 0;
}

#endif

#include "cpu/exec/template-end.h"
